package com.spider.admin.agent;

import com.spider.admin.conf.CommandExecResult;
import com.spider.admin.conf.ENVConf;
import com.spider.admin.conf.ResultMessage;
import com.spider.admin.conf.StructVar;
import com.spider.admin.exception.SpiderException;
import com.spider.admin.store.primary.mapper.AgentConfMapper;
import com.spider.admin.store.primary.model.AgentConf;
import com.spider.admin.utils.FileUtils;
import com.spider.admin.utils.OSCommandUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@Slf4j
@Component
public class AgentServer {

    @Autowired
    private ENVConf envConf;

    @Autowired
    private AgentConfMapper agentConfMapper;

    /**
     * 复制生成代理服务容器
     */
    public void createAgentServer() {
        try {
            String uiContainerBasePath = envConf.getUiContainerBasePath();
            String agentContainerBasePath = uiContainerBasePath + "_agent";
            String lockFile = "agentServer.lock";
            Path lockFileP = Paths.get(System.getProperty("user.dir"), lockFile);
            boolean locked = Files.exists(lockFileP);
            if (!locked) {
                File srcFolder = new File(uiContainerBasePath);
                File targetFolder = new File(agentContainerBasePath);
                if (targetFolder.exists()) {
                    FileUtils.deleteDirectoryRecursively(agentContainerBasePath);
                }
                FileUtils.copyFolder(srcFolder, new File(agentContainerBasePath.replace(targetFolder.getName(), "")), targetFolder.getName());
                lockFileP.toFile().createNewFile();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 启动代理服务容器
     */
    public void startAgentServer() {
        try {
            if (OSCommandUtil.hasRunPort(envConf.getAgentRunPort())) {
                throw new Exception("代理服务端口(" + envConf.getUiRunPort() + ")已经占用");
            }
            String[] excFileInfos = findAgentContainerExeFile();
            OSCommandUtil.executeCmd(excFileInfos[0], " start " + excFileInfos[1], false, false);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage() + "----代理服务容器启动失败");
        }
    }


    private String[] findAgentContainerExeFile() {
        String[] strs = new String[2];
        strs[0] = envConf.getUiContainerBasePath() + "_agent";
        ;
        if (OSCommandUtil.isWinOS()) {
            strs[1] = "nginx.exe";
        } else {
            strs[0] = strs[0] + "\\bin";
            strs[1] = "openrestry";
        }
        Path filePath = Paths.get(strs[0], strs[1]);
        boolean bol = Files.exists(filePath);
        if (bol) {
            return strs;
        } else {
            return null;
        }
    }

    /**
     * 检查代理容器运行状态
     *
     * @return
     */
    public boolean checkAgentServerRunStatus() {
        return OSCommandUtil.hasRunPort(envConf.getAgentRunPort());
    }

    public void reloadAgent() {
        if (checkAgentServerRunStatus()) {
            String[] excFileInfos = findAgentContainerExeFile();
            OSCommandUtil.executeCmd(excFileInfos[0], excFileInfos[1] + " -s reload ", true, false);
        } else {
            throw new RuntimeException("代理服务未启动");
        }
    }

    public void stopAgent() {
        if (checkAgentServerRunStatus()) {
            String[] excFileInfos = findAgentContainerExeFile();
            OSCommandUtil.executeCmd(excFileInfos[0], excFileInfos[1] + " -s stop ", true, false);
        }
    }

    /**
     * 验证代理配置文件
     *
     * @param confId
     * @return
     */
    public boolean validateAgentConf(String confId) throws SpiderException {
        boolean validatePass = false;
        try {
            AgentConf agentConf = agentConfMapper.getAgentConfById(confId);
            if (agentConf != null && StringUtils.isNotEmpty(agentConf.getConfContext())) {
                String fileName = agentConf.getPid() + ".conf";
                String validateConfTempFile = envConf.getUiContainerBasePath() + "_agent/conf/tempConf/" + fileName;
                String commandPath = envConf.getUiContainerBasePath() + "_agent";
                String command = "nginx -t -c " + validateConfTempFile;

                if (!OSCommandUtil.isWinOS()) {
                    validateConfTempFile = envConf.getUiContainerBasePath() + "_agent/nginx/conf/tempConf/" + fileName;
                    commandPath = envConf.getUiContainerBasePath() + "_agent/nginx/bin";
                    command = "openresty -t -c " + validateConfTempFile;
                }
                FileUtils.writeFile(validateConfTempFile, agentConf.getConfContext());
                CommandExecResult commandExecResult = OSCommandUtil.executeCmd(commandPath, command, true, true);
                validatePass = commandExecResult.isSuccess();
                if(!validatePass){
                    agentConfMapper.updateConfStatus(confId, StructVar.AGENT_CONF_CONTEXT_STATUS_VAL_FAIL);
                    throw new SpiderException(ResultMessage.FAILED_PARAMS_VALIDATE.getCode(),commandExecResult.getResultMessage());
                }else{
                    agentConfMapper.updateConfStatus(confId, StructVar.AGENT_CONF_CONTEXT_STATUS_VAL_OK);
                }
                log.info(commandExecResult.toString());
            }
        } catch (Exception e) {
            throw new SpiderException(ResultMessage.FAILED_OS_EXEC_COMMAND.getCode(), "\n" + e.getMessage());
        }

        return validatePass;
    }

}
